#!/usr/bin/python

"""
This script is run once to configure the project specific
json objects and sync script that would change on a site-by-site
basis

it specifically reads a file called 'settings.json' that has
3 objects inside of it described below.  Any member that starts with an "_" 
is ignored.

"project_settings" defines the information regarding where to send files and
find files on the webserver.  It has the following members:
    "webserver_fqdn": The fully qualified domain name of the webserver that 
                      can have files ssh'd to it.  Ex: "cardinal.stanford.edu"
    "webserver_user": User on the webserver that has an ssh account: Ex: "rpsharp"
    "webserver_path": The relative path to copy files (html + javascript, etc.)  
                      Ex: "WWW/inseam-test"
    "cgi_disk_path": The relative path to copy php files on the webserver,
                     often this is not the same location as the regular web
                     files.  Ex: "cgi-bin/inseam-test"
    "cgi_web_path": The relative location of the php files on the url 
                    with respect to the url path in the browser.
                    The application will prepend this to any cgi scripts
                    it needs to run.  Ex: url is www.foo.com/a/b.  If
                    cgi_disk_path = 'cgi-bin/inseam-test' then 
                    cgi_web_path should = '../../cgi-bin/inseam-test' which
                    would yield a relative url of 
                    www.foo.com/a/b/../../cgi-bin/inseam-test

"database_credentials" defines information the php files need to access the 
database on the backend.  It has the following members:
      "server_fqdn": Fully qualified domain name of the database server.  
                     Ex: "mysql-user.stanford.edu"
      "database_name": Name of the database that contains the table defined 
                       in another member.  Ex: "g_natcap_natcap"
      "table_name": Name of the table that contains the inseam data for saving
                    and loading.  Ex: "inseam_data"
      "database_user": The database user, should have write and read permission
                       on the table.  Ex: "gnatcapnatcap0"
      "database_password": Database password for the given user.
                          Ex: "jabbathehat"

"user_overlays" defines information about which predefined layers should be shown
on the explorer and annotater map.  It has two members:

      "layers": An array of geojson files defining polygons Ex: 
                ["data/cpregions.geojson", "data/Coastal_Reserves.geojson", 
                    "data/SPAG2003.geojson"],
      "rasters": EXPERIMENTAL 
      "zoom": The default map zoom level when the explorer opens 
              if no layers are defined.
      "lat": The defalut latitude coordinate to center the explorer map on 
              if no layers are defined.
      "lng": The default longitude coordinate to center the explorer map on 
              if no layers are defined.

"user_metadata" defines what sort of information should be gathered when the
logs in.  Supports text fields or drop down selection boxes.  
Text field is specified by an object as shown in this example:
  "email": {
    "type": "text",
    "label": "Email Address"
  }
Selections are specified as an object like this example:
  "district": {
    "type": "select",
    "label": "District",
    "value": [
      "Ambergris",
      "Belize City",
      "Caye Caulker",
      "Dangriga",
      "Lighthouse Reef",
      "Northern District",
      "Placencia",
      "Southern District",
      "Turneffe Atoll"
    ]
  }

"shape_metadata" defines what should popup when the user draws a new shape:
      "title": This is the title on the dialog that pops up.  
               Ex: "Enter Information about Feature",
      "elements": A json array containing the kinds of data to query the user.
                  No limit on the nubmer of features.  Currently only supports
                  text box and radio button.  Ex: 
        {
          "type": "radio",
          "label": "Feature Category",
          "values": [
            "Existing",
            "Future"
          ],
          "id": "Feature-Type"
        },
        {
          "type": "text",
          "id": "Description",
          "label": "Description"
        }
"""

import json
import sys
import re

settingsFile = 'settings.json'

if len(sys.argv) == 2:
    settingsFile = sys.argv[1]

cfgfile = open(settingsFile, 'r')

try:
    cfgmap = json.loads(cfgfile.read())
except ValueError as e:
    print "Deployment failed because of a parse error in " + settingsFile + ":"
    print e
    print "Check the line specified above in " + settingsFile + "."
    sys.exit(1)

#Generate shape and user metadata json objects
for name in ['shape_metadata', 'user_metadata', 'user_overlays']:
    filename = 'data/' + name + '.json'
    print 'Generating ' + filename + '...'
    file = open(filename, 'w')
    file.write(json.dumps(cfgmap[name]))
    file.close()

#Generate credentials.php
print 'Generating cgi-bin/credentials.php...'
database_settings = cfgmap['database_credentials']
file = open('cgi-bin/credentials.php', 'w')
file.write('<?php\n')
for x in database_settings:
    if x[0] == '_': continue #check for comment
    file.write('$' + x + ' = "' + database_settings[x] + '";\n')
file.write('?>\n')
file.close()

#Generate sync script
print 'Generating sync.sh...'
sync_settings = cfgmap['project_settings']
file = open('sync.sh', 'w')
file.write('#!/bin/bash\n')
file.write('ssh ' + sync_settings['webserver_user'] + '@' + sync_settings['webserver_fqdn'] + ' echo Connection successful! && ')
file.write('./utils/setpermissions.sh && ')
file.write('ssh ' + sync_settings['webserver_user'] + '@' + sync_settings['webserver_fqdn'] + ' mkdir -p ' + sync_settings['webserver_path'] + ' || exit 1;\n')

#build up remote chmod script/
chmodScript = 'DIR=' + ('/' if re.match('^/', sync_settings['webserver_path']) else '') + ';'
chmodScript += 'for i in ' + " ".join(sync_settings['webserver_path'].split('/')) + ";"
chmodScript += "do DIR=\$DIR\$i/;chmod a+x \$DIR; done"
file.write('echo "' + chmodScript + '" > chmodscript.sh && ')
file.write('echo "copying script over" && scp ./chmodscript.sh ' + sync_settings['webserver_user'] + '@' + sync_settings['webserver_fqdn'] + ': && ')
file.write('echo "executing remote script" && ssh ' + sync_settings['webserver_user'] + '@' + sync_settings['webserver_fqdn'] + ' bash chmodscript.sh && ')
file.write('echo "removing remote script" && ssh ' + sync_settings['webserver_user'] + '@' + sync_settings['webserver_fqdn'] + ' rm chmodscript.sh || exit 1;\n')

file.write('ssh ' + sync_settings['webserver_user'] + '@' + sync_settings['webserver_fqdn'] + ' chmod -Rf a+rx ' + re.findall("^.[^/]*", sync_settings['webserver_path'])[0] + '; ')
file.write('rsync -avP --exclude=cgi-bin --exclude=utils --exclude=*.sh --exclude=settings* ./* ' + sync_settings['webserver_user'] + '@' + sync_settings['webserver_fqdn'] + ':' + sync_settings['webserver_path'] + ' && ')
file.write('rsync -avP --exclude=initalize_database.php ./cgi-bin/*.php ' + sync_settings['webserver_user'] + '@' + sync_settings['webserver_fqdn'] + ':' + sync_settings['cgi_disk_path'] + ' || exit 1\n')
file.close()

print 'Generating data/project_settings.json'
file = open('data/project_settings.json', 'w')
file.write('{"cgi_web_path":"' + sync_settings['cgi_web_path'] + '"}')
file.close()

print '\nConfiguration complete.  To push InSEAM to the sever, execute:\n\n./sync.sh'
